package form;

import java.util.ArrayList;
import java.util.Collection;

import validate.AbstractValidator;
import validate.NotEmptyValidator;

abstract public class FormField extends FormElement
{
	protected String name;
	
	protected Object value;
	
	protected String label;
	
	protected ArrayList<AbstractValidator> validators = new ArrayList<AbstractValidator>();
	
	protected ArrayList<String> errors = new ArrayList<String>();
	
	protected boolean required = false;
	
	// Validator to check required elements.
	private static NotEmptyValidator requiredValidator = new NotEmptyValidator();
	
	public FormField(String name)
	{
		this.name = name;
	}
	
	public String getName()
	{
		return name;
	}
	
	public void setValue(Object value)
	{
		this.value = value;
	}
	
	public Object getValue()
	{
		return value;
	}
	
	public void clear()
	{
		setValue(null);
		
		errors.clear();
	}
	
	public void setLabel(String label)
	{
		this.label = label;
	}
	
	public String getLabel()
	{
		return label;
	}
	
	public void addValidator(AbstractValidator validator)
	{
		validators.add(validator);
	}
	
	public void addValidators(Collection<AbstractValidator> validators)
	{
		this.validators.addAll(validators);
	}
	
	public void removeValidator(AbstractValidator validator)
	{
		validators.remove(validator);
	}
	
	public void removeValidators()
	{
		validators.clear();
	}
	
	public void setRequired()
	{
		setRequired(true);
	}
	
	public void setRequired(boolean required)
	{
		this.required = required;
		
		if (required)
		{
			addValidator(requiredValidator);
		}
		else
		{
			removeValidator(requiredValidator);
		}
	}
	
	public boolean isRequired()
	{
		return required;
	}
	
	public boolean isValid()
	{
		boolean valid = true;
		
		String input = (String) getValue();
		
		for (AbstractValidator validator: validators)
		{
			if (!validator.validate(input))
			{
				valid = false;
				
				addError(validator.getErrorMessage());
			}
		}
		
		return valid;
	}
	
	public void addError(String error)
	{
		errors.add(error);
	}
	
	@Override
	public String getCode()
	{
		String code = "<div class=\"form-element form-field\">";
		
		if (label != null && !label.isEmpty())
		{
			code += "<label for=\"" + name + "\">" + label + "</label><br />";
		}
		
		setAttribute("id", name);
		setAttribute("name", name);
		
		prepareValue();
		
		code += getElementCode();

		if (!errors.isEmpty())
		{
			code += "<ul class=\"errors\">";
			
			for (String error: errors)
			{
				code += ("<li>" + error + "</li>");
			}
			
			code += "</ul>";
		}
		
		code += "</div>";
		
		return code;
	}
	
	abstract protected void prepareValue();
}
